local skynet = require "skynet"
require "skynet.manager"
local mongo = require "skynet.db.mongo"
local log = require "sky_log"
local queue = require "skynet.queue"
local Queue = queue()

local M = {
    mogo_connect_t = {},
}

function M:connect_mongo(config)
    if not self.mysql_connect_t then
        self.mysql_connect_t = {}
    end
    if not tonumber(config.plat_id) then
        log.error("mongo connect error: no plat_id!")
        return
    end

    local index = config.plat_id
    self.mogo_connect_t[index] = {}
    local conf = {}
    conf.host = string.match(config.mongo_master_host, "(%S+):")
    conf.port = tonumber(string.match(config.mongo_master_host, ":(%d+)"))
    -- conf.authdb = "admin"

    local client = mongo.client(conf)
    if client then
        -- log.debug("connect plat_id ["..config.plat_id.."] mongo success")
        self.mogo_connect_t[index] = conf
        self.mogo_connect_t[index].client = client
    end
end

function M:findone(plat_id, args)
    if not plat_id
    or not args
    or not self.mogo_connect_t[plat_id] then
        log.error("findone error!"..
            "| plat_id:"..(plat_id or "nil")
        )
        return
    end

    local client = self.mogo_connect_t[plat_id].client
    local db = client:getDB(args.database)
    local c = db:getCollection(args.collection)
    local cursor = c:find(args.query, args.selector)
    if args.skip ~= nil then
        cursor:skip(args.skip)
    end
    if args.limit ~= nil then
        cursor:limit(args.limit)
    end

    local doc = {}
    if cursor:hasNext() then
        local data = cursor:next()
        table.insert(doc, data)
    end
    cursor:close()
    return doc
end

function M:findall(plat_id, args)
    if not plat_id
    or not self.mogo_connect_t[plat_id] then
        log.error("findall error!"..
            "| plat_id:"..(plat_id or "nil")
        )
        return
    end

    local client = self.mogo_connect_t[plat_id].client
    local db = client:getDB(args.database)
    local c = db:getCollection(args.collection)
    local cursor = c:find(args.query, args.selector)
    if args.skip ~= nil then
        cursor:skip(args.skip)
    end
    if args.limit ~= nil then
        cursor:limit(args.limit)
    end

    local doc = {}
    while cursor:hasNext() do
        local data = cursor:next()
        table.insert(doc, data)
    end
    cursor:close()
    return doc
end

function M:update(plat_id, args)
    if not plat_id
    or not self.mogo_connect_t[plat_id] or not args or not args.selector then
        log.error("findall error!"..
            "| plat_id:"..(plat_id or "nil")
        )
        return
    end

    local client = self.mogo_connect_t[plat_id].client
    local db = client:getDB(args.database)
    local c = db:getCollection(args.collection)
    c:update(args.selector, args.update, args.upsert, args.multi)
end


function M:init_by_config(config)
    self:connect_mongo(config)
end

skynet.start(function ()
    skynet.dispatch("lua", function(session, address, cmd, ...)
        local f = M[cmd]
        if f then
            skynet.ret(skynet.pack(Queue(f, M, ...) ) )
        else
            skynet.error(string.format("Unknown command %s", tostring(cmd)))
        end
    end)

    skynet.register(".mongo")
end)

return M